package br.com.tiespec.ejb.Ejb;

import java.io.Serializable;

import javax.ejb.Singleton;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.SessionFactoryObserver;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;

import br.com.tiespec.model.Modelo.Anexo;
import br.com.tiespec.model.Modelo.Artefato;
import br.com.tiespec.model.Modelo.Ator;
import br.com.tiespec.model.Modelo.Cenario;
import br.com.tiespec.model.Modelo.CenarioBase;
import br.com.tiespec.model.Modelo.ClientePortal;
import br.com.tiespec.model.Modelo.ClienteProjeto;
import br.com.tiespec.model.Modelo.ConfigDescricaoEstendida;
import br.com.tiespec.model.Modelo.Contato;
import br.com.tiespec.model.Modelo.Dado;
import br.com.tiespec.model.Modelo.DescricaoEstendida;
import br.com.tiespec.model.Modelo.Documento;
import br.com.tiespec.model.Modelo.EntidadeGenerica;
import br.com.tiespec.model.Modelo.Fluxo;
import br.com.tiespec.model.Modelo.FluxoBase;
import br.com.tiespec.model.Modelo.Perfil;
import br.com.tiespec.model.Modelo.Plano;
import br.com.tiespec.model.Modelo.Projeto;
import br.com.tiespec.model.Modelo.Usuario;

@Singleton
public class HibernateSingleton implements Serializable {

	private static final long serialVersionUID = 545998617432679130L;

	public HibernateSingleton() { }
    
    private static final SessionFactory sessionFactory;
    private static final ServiceRegistry serviceRegistry;
    
    static {
        Configuration config = getConfiguration();
       
        serviceRegistry = new ServiceRegistryBuilder().applySettings(
                config.getProperties()).buildServiceRegistry();
       
        config.setSessionFactoryObserver(new SessionFactoryObserver() {
 
			private static final long serialVersionUID = 2037905499819742096L;

			@Override
            public void sessionFactoryCreated(SessionFactory factory) { }
 
            @Override
            public void sessionFactoryClosed(SessionFactory factory) {
                ServiceRegistryBuilder.destroy(serviceRegistry);
            }
        });
       
        sessionFactory = config.buildSessionFactory(serviceRegistry);
    }
    
    public Session getSession() {
		if (!sessionFactory.getCurrentSession().isOpen()){
			return sessionFactory.openSession();
		}
		return sessionFactory.getCurrentSession();
	}
    
    private static Configuration getConfiguration() {
        Configuration cfg = new Configuration();
              
        /**
         * MAPEAMENTO DAS CLASSES GERENCIADAS PELO HIBERNATE
         */
        cfg.addAnnotatedClass(Anexo.class);
        cfg.addAnnotatedClass(Artefato.class);
        cfg.addAnnotatedClass(Ator.class);
        cfg.addAnnotatedClass(Cenario.class);
        cfg.addAnnotatedClass(CenarioBase.class);
        cfg.addAnnotatedClass(ClientePortal.class);
        cfg.addAnnotatedClass(ClienteProjeto.class);
        cfg.addAnnotatedClass(ConfigDescricaoEstendida.class);
        cfg.addAnnotatedClass(Contato.class);
        cfg.addAnnotatedClass(Dado.class);
        cfg.addAnnotatedClass(DescricaoEstendida.class);
        cfg.addAnnotatedClass(Documento.class);
        cfg.addAnnotatedClass(EntidadeGenerica.class);
        cfg.addAnnotatedClass(Fluxo.class);
        cfg.addAnnotatedClass(FluxoBase.class);
        cfg.addAnnotatedClass(Perfil.class);
        cfg.addAnnotatedClass(Plano.class);
        cfg.addAnnotatedClass(Projeto.class);
        cfg.addAnnotatedClass(Usuario.class);
        
        /**
         * CONGIGURAÇÕES DE CONEXÃO COM A BASE DE DADOS
         */
        
        cfg.setProperty("hibernate.connection.datasource", "jdbc/tiespec");
		cfg.setProperty("hibernate.connection.driver_class", "org.postgresql.Driver");
		cfg.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
		
//		cfg.setProperty("hibernate.connection.url", "jdbc:postgresql://localhost:5432/ti_tcc");
//		cfg.setProperty("hibernate.connection.username", "geen");
//		cfg.setProperty("hibernate.connection.password", "geen");
		
//		cfg.setProperty("hibernate.connection.driver_class", "com.mysql.jdbc.Driver");
//		cfg.setProperty("hibernate.connection.url", "jdbc:mysql://localhost:3306/tiespec");
//		cfg.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
//		cfg.setProperty("hibernate.connection.username", "root");
//		cfg.setProperty("hibernate.connection.password", "");
		
        cfg.setProperty("hibernate.current_session_context_class", "thread");
        cfg.setProperty("hibernate.hbm2ddl.auto", "update");
        
        cfg.setProperty("hibernate.connection.autocommit", "false");
        cfg.setProperty("hibernate.cache.provider_class", "org.hibernate.cache.NoCacheProvider");
        cfg.setProperty("hibernate.transaction.factory_class", "org.hibernate.transaction.JDBCTransactionFactory");
        
        /**
         * OPÇÕES DE DEBUG
         */
        cfg.setProperty("hibernate.show_sql", "false");
        cfg.setProperty("hibernate.format_sql", "false");
        cfg.setProperty("hibernate.generate_statistics", "false");
        cfg.setProperty("hibernate.use_sql_comments", "false");
        
        return cfg;
    }
}
